// Juego de laberinto
// Samuel Garcia, Pablo Tarraga

using System;

public class Labyrinth
{
    public struct Objeto
    {
        public char simbolo;
        public bool existeObjeto;
        public int posObjetoX;
        public int posObjetoY;
    }
    
    public static void Main()
    {
        // ------------- Intro ------------- 
        
        Console.ForegroundColor = ConsoleColor.Yellow;
        int opcion;
        bool juego = false;
        bool salir = false;

        do
        {
            Console.Clear();
            
            for (int col = 0; col < 6; col++)
            {
                Console.SetCursorPosition(25, col);
                Console.WriteLine("*");
                Console.SetCursorPosition(53, col);
                Console.WriteLine("*");
            }

            Console.SetCursorPosition(25, 0);
            Console.WriteLine("*****************************");
            Console.SetCursorPosition(25, 5);
            Console.WriteLine("*****************************");

            Console.SetCursorPosition(27, 2);
            Console.WriteLine ("¡Bienvenido al laberinto!");
            Console.SetCursorPosition(33, 3);
            Console.WriteLine ("V0.0.6");

            Console.SetCursorPosition(0, 8);
            Console.WriteLine("1. Jugar");
            Console.WriteLine("2. Nivel");
            Console.WriteLine("3. Estadisticas");
            Console.WriteLine();
            Console.WriteLine("0. Salir");
            
            Console.WriteLine();
            
            Console.Write("Elige una opcion: ");
            opcion = Convert.ToInt32(Console.ReadLine());
            
            switch (opcion)
            {
                case 1:
                    juego = true;
                    break;
                case 2:
                    Console.Clear();
                    Console.SetCursorPosition(25, 10);
                    Console.WriteLine("Función aun no implementada.");
                    Console.SetCursorPosition(25, 11);
                    Console.WriteLine("Pulsa INTRO para volver al menú.");
                    Console.ReadLine();
                    break;
                case 3:
                    Console.Clear();
                    Console.SetCursorPosition(25, 10);
                    Console.WriteLine("Función aun no implementada.");
                    Console.SetCursorPosition(25, 11);
                    Console.WriteLine("Pulsa INTRO para volver al menú.");
                    Console.ReadLine();
                    break;
                case 0:
                    salir = true;
                    break;                
                default:
                    Console.WriteLine("Elige una opcion valida");
                    break;
            }
        }
        while (juego == false && salir == false);   
        
        // ------------- Juego -------------
                
        // POSICION INICIAL DEL JUGADOR EN EL TABLERO
        int posTableroX = 17, posTableroY = 4;

        // POSICION INICIAL DEL JUGADOR EN LA CONSOLA
        int posTotalX = 25 + posTableroX; 
        int posTotalY = 10 + posTableroY;
        
        // OBJETOS
        const int NUMERO_OBJETOS = 2;
        Objeto [] objetos = new Objeto [NUMERO_OBJETOS];
        /* Objeto 0 - Llave
         * Objeto 1 - Puerta */
        
        // SIMBOLO LLAVE Y PUERTA
        objetos[0].simbolo = 'k'; objetos[1].simbolo = '|';

        // CONDICIONES QUE MODIFICAN LA PARTIDA
        bool muerto = false; 
        objetos[0].existeObjeto = false; objetos[1].existeObjeto = false;

        // VARIABLES PARA LA POSICION DE LA LLAVE Y DE LA PUERTA
        objetos[0].posObjetoX = 28; objetos[0].posObjetoY = 7; 
        objetos[1].posObjetoX = 0; objetos[1].posObjetoY = 1;

        Random rand = new Random();
        ConsoleKeyInfo tecla = new ConsoleKeyInfo();

        string  [] tablero =
        {
            "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
            "X   XX     X   XX      XX    XX",
            "XX    XXX  X  XX   XX     X  XX",
            "XX  X      X   X  XXXXXX  X   X",
            "X      XXXXX      X       XX  X",
            "X  XXX        XXXX   X  XX    X",
            "X   XXXX  X  X      XX  XX  XXX",
            "X   XX    X     XX  XX   X   XX",
            "XX      XXX  XXX      X     XXX",
            "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
         };  

        // CREACION DE LA LLAVE Y LA PUERTA
        do
        {
            if (tablero[objetos[0].posObjetoY][objetos[0].posObjetoX] != 'X')
            {
                    objetos[0].existeObjeto = true;
            }
        }
        while (!objetos[0].existeObjeto);
        
        do
        {
            objetos[1].posObjetoX = rand.Next(1, 7);
        }
        while (objetos[1].posObjetoX != 6 && objetos[1].posObjetoX != 1); 
    
        do
        {
            if (tablero[objetos[1].posObjetoY][objetos[1].posObjetoX] != 'X')
            {
                objetos[1].existeObjeto = true;
            }
        }
        while (!objetos[1].existeObjeto);
        
        // LA PUERTA NO APARECERÁ HASTA QUE NO SE HAYA RECOGIDO LA LLAVE
        objetos[1].existeObjeto = false;

        if (!salir)
        {
            do
            {
                Console.Clear();
                Console.SetCursorPosition(29, 0);
                Console.WriteLine("Presiona ESC para salir");
                
                // SE IMPRIME EL TABLERO
                for (int i = 0; i < tablero.Length; i++)
                {
                    Console.SetCursorPosition(25, 10 + i);
                    Console.WriteLine(tablero[i]);
                }
                
                // SE COMPRUEBA LA CASILLA DE LA PUERTA
                if (!objetos[0].existeObjeto && (posTableroX == objetos[1].posObjetoX) && 
                    (objetos[1].posObjetoY == posTableroY))
                {
                    Console.SetCursorPosition(5, 20);
                    Console.WriteLine("La puerta esta cerrada.");
                    Console.SetCursorPosition(5, 21);
                    Console.WriteLine("Pulsa K para usar la llave.");
                }
                
                // SE COMPRUEBA LA CASILLA DE LA LLAVE
                if ((posTableroX == objetos[0].posObjetoX) && 
                    (posTableroY == objetos[0].posObjetoY))
                {
                    if (objetos[0].existeObjeto)
                    {
                        Console.SetCursorPosition(5, 22);
                        Console.WriteLine("Has encontrado una llave.");
                    }
                    objetos[0].existeObjeto = false;
                    objetos[1].existeObjeto = true;
                }
                
                // SE IMPRIME LA PUERTA
                if (objetos[1].existeObjeto)
                {
                    Console.SetCursorPosition(25 + objetos[1].posObjetoX, 
                        10 + objetos[1].posObjetoY);
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.BackgroundColor = ConsoleColor.DarkGray;
                    Console.Write(objetos[1].simbolo);
                    Console.BackgroundColor = ConsoleColor.Black;
                }
                
                // SE IMPRIME LA LLAVE SI EXISTE
                if (objetos[0].existeObjeto) 
                {
                    Console.SetCursorPosition(25 + objetos[0].posObjetoX, 
                        10 + objetos[0].posObjetoY);
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.Write(objetos[0].simbolo);
                }
                
                // SE IMPRIME EL ICONO DEL JUGADOR
                Console.SetCursorPosition(posTotalX, posTotalY);
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("@");
                Console.ForegroundColor = ConsoleColor.Yellow;
                 
                /* MOVIMIENTOS DEL JUGADOR
                SI SE INTENTA MOVER EN UNA DIRECCIÓN Y HAY UNA PARED 'X'
                EL MOVIMIENTO NO SE REALIZA*/
                tecla = Console.ReadKey();
                
                if (tecla.KeyChar == 'w' || tecla.Key == ConsoleKey.UpArrow)
                {
                    if (tablero[posTableroY - 1][posTableroX] != 'X')
                    {
                        posTotalY--;
                        posTableroY--;
                    }
                }
                if (tecla.KeyChar == 's' || tecla.Key == ConsoleKey.DownArrow)
                {
                    if (tablero[posTableroY + 1][posTableroX] != 'X')
                    {
                        posTotalY++;
                        posTableroY++;
                    }
                }
                if (tecla.KeyChar == 'a' || tecla.Key == ConsoleKey.LeftArrow)
                {
                    if (tablero[posTableroY][posTableroX - 1] != 'X')
                    {
                        posTotalX--;
                        posTableroX--;
                    }
                }
                if (tecla.KeyChar == 'd' || tecla.Key == ConsoleKey.RightArrow)
                {
                    if (tablero[posTableroY][posTableroX + 1] != 'X')
                    {
                        posTotalX++;
                        posTableroX++;
                    }
                }
                  
                if (!objetos[0].existeObjeto && (posTableroX == objetos[1].posObjetoX) && 
                    (objetos[1].posObjetoY == posTableroY)&& 
                        (tecla.KeyChar == objetos[0].simbolo))
                {
                    Console.Clear();
                    Console.SetCursorPosition(25, 10);
                    Console.WriteLine("La puerta se ha abierto!.");
                    Console.SetCursorPosition(25, 11);
                    Console.WriteLine("Nivel completado.");
                    Console.SetCursorPosition(25, 13);
                    Console.WriteLine("Pulsa INTRO para continuar.");
                    salir = true;
                    Console.ReadLine();
                }

                // SI SE PULSA ESC, SE SALE DE LA PARTIDA
                if (tecla.Key == ConsoleKey.Escape)
                {
                    Console.Clear();
                    salir = true;
                }
            }
            while (!salir && !muerto);
        }

        int calaveraX = 23;
        if (muerto)
        {
            Console.ForegroundColor=ConsoleColor.White;
            Console.Clear();
            Console.SetCursorPosition(calaveraX, 5);
            Console.WriteLine("..###'                       '###,.");
            Console.SetCursorPosition(calaveraX, 6);
            Console.WriteLine(" ´####;       .ooooo.       ;####'");
            Console.SetCursorPosition(calaveraX, 7);
            Console.WriteLine("    ´##,   .o8P'''''Y8o.   ,##'");
            Console.SetCursorPosition(calaveraX, 8);
            Console.WriteLine("     '##, 88'         '88 ,##'");
            Console.SetCursorPosition(calaveraX, 9);
            Console.WriteLine("      '##8'             '8##'");
            Console.SetCursorPosition(calaveraX, 10);
            Console.WriteLine("       '#8   ,o.   .o,   8#'");
            Console.SetCursorPosition(calaveraX, 11);
            Console.WriteLine("         8 8 888; :888 8 8");
            Console.SetCursorPosition(calaveraX, 12);
            Console.WriteLine("         8P '88'   '88' Y8");
            Console.SetCursorPosition(calaveraX, 13);
            Console.WriteLine("         P       8      'Y");
            Console.SetCursorPosition(calaveraX, 14);
            Console.WriteLine("         b      888      d");
            Console.SetCursorPosition(calaveraX, 15);
            Console.WriteLine("          `8b         d8`");
            Console.SetCursorPosition(calaveraX, 16);
            Console.WriteLine("           88''88888''88");
            Console.SetCursorPosition(calaveraX, 17);
            Console.WriteLine("           8 `'''''''` 8");
            Console.SetCursorPosition(calaveraX, 18);
            Console.WriteLine("            `8ooooooo8`");
            Console.SetCursorPosition(calaveraX, 19);
            Console.WriteLine("            ,##'   '##,");
            Console.SetCursorPosition(calaveraX, 20);
            Console.WriteLine("           ,##'     '##,");
            Console.SetCursorPosition(calaveraX, 21);
            Console.WriteLine("          ,##'       '##,");
            Console.SetCursorPosition(calaveraX, 22);
            Console.WriteLine("       .#####,       ,#####.");
            Console.SetCursorPosition(calaveraX, 23);
            Console.WriteLine("          `##'       '##`");
            Console.ForegroundColor=ConsoleColor.Red;
            Console.SetCursorPosition(36, 27);
            Console.WriteLine("GAME OVER");
            Console.ReadLine();
        }
        Console.ForegroundColor = ConsoleColor.White;
        Console.BackgroundColor = ConsoleColor.Black;
        Console.Clear();
    }
}

/* ------------------------------------------

Próximas versiones

v0.0002 - Contendrá objetos aleatorios en pantalla y al pasar por encima de ellos el objeto desaparecerá. En versiones futuras se utilizarán para añadir vidas/invencibilidad.

v0.0003 - Definir bordes en pantalla y limitar que no pueda traspasarlos y evitar que falle el programa.

v0.0004 - Vidas. En la parte inferior del marco de la pantalla añadiremos dos contadores, uno que muestre las vidas actuales del personaje y un contador de puntos que irá aumentando respecto a los objetos recogidos.

v0.0005 - Superar Nivel. Al recoger todos los objetos en pantalla mostrará un cartel de nivel superado y terminará el juego. 

v0.0006 - Laberinto. Se imprimirá el primer nivel del laberinto.

v0.0007 - Al superar el nivel del laberinto, mostrará un contador de cuantos niveles nos faltan para llegar al final. Dibujo de la princesa en una jaula con el minotauro.

v0.0008 - Añadiremos a la parte inferior de la pantalla un reloj que mostará el tiempo límite para superar el nivel.

v0.0009 - Añadiremos que el contador parpadeará en diversos colores al faltar menos de 30 segundos para completar el nivel.

PROXIMAMENTE

v0.000X - Cambiar el laberinto al completar el nivel
v0.000X - Completar puzzles para completar el nivel
v0.000X - Mapas aleatorios
v0.000X - Definir campo de visión según niebla de guerra.
v0.000X - Princesa. Mostrar la princesa en el último nivel.
v0.000X - Enemigos. Minotauro.

------------------------------------------ */ 
